package com.dycloud.project.config;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;


/**
 * Redis使用FastJson序列化
 * 
 * @author dycloud
 */
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {

    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

    /**
     * 推荐使用 JSONReader.autoTypeFilter 方式来限制反序列化的类型范围（白名单）
     * 你可以把 Constants.JSON_WHITELIST_STR 设置为一个或多个包名
     * 示例: "com.dycloud.", "com.dycloud.project.security."
     */
    static final JSONReader.AutoTypeBeforeHandler AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(
            // 多个包名可写多个参数
            "com.dycloud.project.security"
    );

    private final Class<T> clazz;

    public FastJson2JsonRedisSerializer(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }

        // WriteClassName 保留 @type 字段，方便反序列化时还原具体类型
        return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName)
                .getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }

        String str = new String(bytes, DEFAULT_CHARSET);

        // 使用自动类型 + 白名单解析
        return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER, JSONReader.Feature.SupportAutoType);
    }
}

